// 蜂窝蜜造平台生成代码，如手工更改，请添加到 .beeignore 忽略生成
package com.fowo.api.controller;

import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.fowo.api.common.model.IdListPo;
import com.fowo.api.common.model.IdPo;
import com.fowo.api.common.model.ImportRow;
import com.fowo.api.common.model.OptionItem;
import com.fowo.api.common.model.R;
import com.fowo.api.common.util.ResponseUtils;
import com.fowo.api.entity.StockOutRawMaterial;
import com.fowo.api.model.stock.out.raw.material.StockOutRawMaterialImportPo;
import com.fowo.api.model.stock.out.raw.material.StockOutRawMaterialItemVo;
import com.fowo.api.model.stock.out.raw.material.StockOutRawMaterialSearchParamPo;
import com.fowo.api.model.stock.out.raw.material.StockOutRawMaterialVo;
import com.fowo.api.service.StockOutRawMaterialService;
import com.fowo.api.sys.entity.SysFile;
import com.fowo.api.user.model.JwtUserInfo;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.tags.Tag;
import java.io.IOException;
import java.io.InputStream;
import java.util.Arrays;
import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;
import javax.annotation.Resource;
import javax.servlet.http.HttpServletResponse;
import org.springframework.core.io.ClassPathResource;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.util.StreamUtils;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

@Tag(name = "原材料出库单")
@RequestMapping("/api/stock-out-raw-material")
@RestController
public class StockOutRawMaterialController {

  @Resource
  private StockOutRawMaterialService service;

  @Operation(summary = "查询结果")
  @GetMapping
  public R<List<StockOutRawMaterialItemVo>> search(
    StockOutRawMaterialSearchParamPo search
  ) {
    JwtUserInfo jwtUserInfo = JwtUserInfo.fromHeader();
    if (jwtUserInfo != null) {
      search.setCurrentUserId(jwtUserInfo.getUserId());
    }
    return R.data(service.search(search));
  }

  @Operation(summary = "快速查询选项(有缓存)")
  @GetMapping("options")
  public R<List<OptionItem<StockOutRawMaterialItemVo>>> searchOptions(
    StockOutRawMaterialSearchParamPo search
  ) {
    JwtUserInfo jwtUserInfo = JwtUserInfo.fromHeader();
    if (jwtUserInfo != null) {
      search.setCurrentUserId(jwtUserInfo.getUserId());
    }
    return R.data(service.searchOptions(search));
  }

  @Operation(summary = "查询最后更新时间")
  @GetMapping("lastUpdateTime")
  public R<Date> searchLastUpdateTime(StockOutRawMaterialSearchParamPo search) {
    JwtUserInfo jwtUserInfo = JwtUserInfo.fromHeader();
    if (jwtUserInfo != null) {
      search.setCurrentUserId(jwtUserInfo.getUserId());
    }
    return R.data(service.searchLastUpdateTime(search));
  }

  @Operation(summary = "获取满足搜索条件的统计信息")
  @GetMapping("statistical")
  public R<?> searchForStatistical(StockOutRawMaterialSearchParamPo search) {
    JwtUserInfo jwtUserInfo = JwtUserInfo.fromHeader();
    if (jwtUserInfo != null) {
      search.setCurrentUserId(jwtUserInfo.getUserId());
    }
    return R.data(service.searchForStatistical(search));
  }

  @Operation(summary = "获取分页查询结果")
  @GetMapping("page")
  public R<Page<StockOutRawMaterialItemVo>> getPage(
    StockOutRawMaterialSearchParamPo search
  ) {
    JwtUserInfo jwtUserInfo = JwtUserInfo.fromHeader();
    if (jwtUserInfo != null) {
      search.setCurrentUserId(jwtUserInfo.getUserId());
    }
    return R.data(service.pageSearch(search));
  }

  @Operation(summary = "获取包括子表的查询结果")
  @GetMapping("page-with-child")
  public R<Page<?>> getPageWithChild(StockOutRawMaterialSearchParamPo search) {
    JwtUserInfo jwtUserInfo = JwtUserInfo.fromHeader();
    if (jwtUserInfo != null) {
      search.setCurrentUserId(jwtUserInfo.getUserId());
    }
    return R.data(service.pageWithChildSearch(search));
  }

  @Operation(summary = "仅获取子表的查询结果")
  @GetMapping("page-only-child/{parentId}")
  public R<Page<?>> getPageOnlyChild(
    @PathVariable Long parentId,
    StockOutRawMaterialSearchParamPo search
  ) {
    JwtUserInfo jwtUserInfo = JwtUserInfo.fromHeader();
    if (jwtUserInfo != null) {
      search.setCurrentUserId(jwtUserInfo.getUserId());
    }
    return R.data(service.pageOnlyChildSearch(parentId, search));
  }

  @Operation(summary = "查询是否后台下载")
  @GetMapping("getBackgroundExportFlag")
  public R<Boolean> getBackgroundExportFlag(
    StockOutRawMaterialSearchParamPo search
  ) {
    JwtUserInfo jwtUserInfo = JwtUserInfo.fromHeader();
    if (jwtUserInfo != null) {
      search.setCurrentUserId(jwtUserInfo.getUserId());
    }
    return R.data(service.getBackgroundExportFlag(search));
  }

  @Operation(summary = "获取详情")
  @GetMapping("{id}")
  public R<StockOutRawMaterialVo> getVoById(@PathVariable Long id) {
    return R.data(() -> service.getVoById(id));
  }

  @Operation(summary = "获取源表ID相关的编号列表")
  @GetMapping("parent-id/{texts}/ids")
  public R<List<Long>> getIdsByParentId(@PathVariable String texts) {
    List<String> nameList = Arrays
      .stream(texts.split(","))
      .collect(Collectors.toList());
    return R.data(() -> service.getIdsByParentId(nameList));
  }

  @Operation(summary = "获取编号相关的源表ID列表")
  @GetMapping("parent-id/{ids}")
  public R<List<String>> getVoById(@PathVariable String ids) {
    List<Long> idList = Arrays
      .asList(ids.split(","))
      .stream()
      .map(Long::valueOf)
      .collect(Collectors.toList());
    return R.data(() -> service.getParentIdByIds(idList));
  }

  @PreAuthorize("@am.canAccess('stockOutRawMaterialCreate')")
  @Operation(summary = "新增")
  @PostMapping
  public R<Long> create(@Validated @RequestBody StockOutRawMaterialVo model) {
    return R.data(() -> service.create(model));
  }

  @PreAuthorize("@am.canAccess('stockOutRawMaterialEdit')")
  @Operation(summary = "更新")
  @PutMapping
  public R update(@RequestBody StockOutRawMaterialVo model) {
    return R.run(() -> service.update(model));
  }

  @PreAuthorize("@am.canAccess('stockOutRawMaterialEdit')")
  @Operation(summary = "编辑更新")
  @PutMapping("edit")
  public R updateForEdit(@RequestBody StockOutRawMaterialVo model) {
    return R.run(() -> service.updateForEdit(model));
  }

  @PreAuthorize("@am.canAccess('stockOutRawMaterialDelete')")
  @Operation(summary = "删除")
  @DeleteMapping("{id}")
  public R delete(@PathVariable Long id) {
    return R.run(() -> service.delete(id));
  }

  @PreAuthorize("@am.canAccess('stockOutRawMaterialDelete')")
  @Operation(summary = "批量删除")
  @DeleteMapping("batch")
  public R batchDelete(@RequestBody IdListPo po) {
    return R.run(() -> service.batchDelete(po.getIds()));
  }

  @PreAuthorize("@am.canAccess('stockOutRawMaterialImport')")
  @Operation(summary = "导入预览")
  @PostMapping("import-preview")
  public R<List<ImportRow<StockOutRawMaterialImportPo>>> importPreview(
    @RequestBody SysFile sysFile,
    @RequestParam(name = "template", required = false) Long templateId,
    @RequestParam(
      name = "allowOverrides",
      defaultValue = "false"
    ) boolean allowOverrides
  ) {
    return R.data(() ->
      service.importPreview(sysFile, templateId, allowOverrides)
    );
  }

  @PreAuthorize("@am.canAccess('stockOutRawMaterialImport')")
  @Operation(summary = "完成导入")
  @PostMapping("import-done")
  public R importDone(
    @RequestBody List<ImportRow<StockOutRawMaterialImportPo>> rows,
    @RequestParam(name = "template", required = false) Long templateId
  ) {
    return R.run(() -> service.importDone(rows, templateId));
  }

  @Operation(summary = "下载导入模版")
  @GetMapping("import/template")
  public void downloadImportTemplate(HttpServletResponse response)
    throws IOException {
    ResponseUtils.setAttachmentFileName(response, "原材料出库单导入模版.xlsx");
    InputStream inputStream = new ClassPathResource(
      "templates/StockOutRawMaterial.xlsx"
    )
      .getInputStream();
    StreamUtils.copy(inputStream, response.getOutputStream());
  }

  @Operation(summary = "导出")
  @GetMapping("export")
  @PreAuthorize("@am.canAccess('stockOutRawMaterialExport')")
  public void export(
    @RequestParam(name = "template", required = false) Long templateId,
    StockOutRawMaterialSearchParamPo search,
    HttpServletResponse response
  ) throws Exception {
    JwtUserInfo jwtUserInfo = JwtUserInfo.fromHeader();
    if (jwtUserInfo != null) {
      search.setCurrentUserId(jwtUserInfo.getUserId());
    }
    service.export(templateId, search, response);
  }

  @PreAuthorize("@am.canAccess('stockOutRawMaterialConfirmationOfDeliverys')")
  @Operation(summary = "确认出库")
  @PostMapping("confirmationOfDeliverys")
  public R confirmationOfDeliverys(@RequestBody IdPo po) {
    return R.run(() -> service.confirmationOfDeliverys(po.getId()));
  }

  @PreAuthorize("@am.canAccess('stockOutRawMaterialPrintOutTheStockLists')")
  @Operation(summary = "打印出库单")
  @PostMapping("printOutTheStockLists")
  public R printOutTheStockLists(@RequestBody IdPo po) {
    return R.run(() -> service.printOutTheStockLists(po.getId()));
  }

  @PreAuthorize("@am.canAccess('stockOutRawMaterialAnnul')")
  @Operation(summary = "撤销")
  @PostMapping("annul")
  public R annul(@RequestBody IdPo po) {
    return R.run(() -> service.annul(po.getId()));
  }

  @PreAuthorize(
    "@am.canAccess('stockOutRawMaterialPrintOutStockSheetTemplates')"
  )
  @Operation(summary = "打印出库单（模版）")
  @PostMapping("printOutStockSheetTemplates")
  public R printOutStockSheetTemplates(@RequestBody IdPo po) {
    return R.run(() -> service.printOutStockSheetTemplates(po.getId()));
  }

  @PreAuthorize("@am.canAccess('stockOutRawMaterialRefer')")
  @Operation(summary = "提交")
  @PostMapping("refer")
  public R refer(@RequestBody IdListPo po) {
    return R.run(() -> service.refer(po.getIds()));
  }

  @PreAuthorize("@am.canAccess('stockOutRawMaterialConfirmationOfDelivery')")
  @Operation(summary = "确认出库")
  @PostMapping("confirmationOfDelivery")
  public R confirmationOfDelivery(@RequestBody IdListPo po) {
    return R.run(() -> service.confirmationOfDelivery(po.getIds()));
  }

  @PreAuthorize("@am.canAccess('stockOutRawMaterialSubmitAndRelease')")
  @Operation(summary = "提交并出库")
  @PostMapping("submitAndRelease")
  public R submitAndRelease(@RequestBody IdListPo po) {
    return R.run(() -> service.submitAndRelease(po.getIds()));
  }

  @PreAuthorize(
    "@am.canAccess('stockOutRawMaterialPrintOutStockSheetTemplate')"
  )
  @Operation(summary = "打印出库单（模版）")
  @PostMapping("printOutStockSheetTemplate")
  public R printOutStockSheetTemplate(@RequestBody IdListPo po) {
    return R.run(() -> service.printOutStockSheetTemplate(po.getIds()));
  }

  @PreAuthorize("@am.canAccess('stockOutRawMaterialPrintOutTheStockList')")
  @Operation(summary = "打印出库单")
  @PostMapping("printOutTheStockList")
  public R printOutTheStockList(@RequestBody IdListPo po) {
    return R.run(() -> service.printOutTheStockList(po.getIds()));
  }

  @PreAuthorize("@am.canAccess('stockOutRawMaterialCustSubmit')")
  @Operation(summary = "提交")
  @PostMapping("custSubmit")
  public R custSubmit(@RequestBody IdPo po) {
    return R.run(() -> service.custSubmit(po.getId()));
  }

  @PreAuthorize("@am.canAccess('stockOutRawMaterialPushStockOut')")
  @Operation(summary = "下推其他入库单")
  @PostMapping("pushStockOut")
  public R pushStockOut(@RequestBody IdPo po) {
    return R.run(() -> service.pushStockOut(po.getId()));
  }

  @PreAuthorize("@am.canAccess('stockOutRawMaterialPushStockInAndStockOut')")
  @Operation(summary = "下推生成入库单和出库单(工厂)")
  @PostMapping("pushStockInAndStockOut")
  public R pushStockInAndStockOut(@RequestBody IdPo po) {
    return R.run(() -> service.pushStockInAndStockOut(po.getId()));
  }

  @PreAuthorize("@am.canAccess('stockOutRawMaterialOutStockApply')")
  @Operation(summary = "审核")
  @PostMapping("outStockApply")
  public R outStockApply(@RequestBody IdPo idPo) {
    return R.run(() -> service.outStockApply(idPo.getId()));
  }

  @PreAuthorize("@am.canAccess('stockOutRawMaterialCancelOutbound')")
  @Operation(summary = "取消审核")
  @PostMapping("cancelOutbound")
  public R cancelOutbound(@RequestBody IdPo idPo) {
    return R.run(() -> service.cancelOutbound(idPo.getId()));
  }

  @PreAuthorize("@am.canAccess('stockOutRawMaterialCreateReceivable')")
  @Operation(summary = "生成应收单")
  @PostMapping("createReceivable")
  public R createReceivable(@RequestBody IdPo po) {
    return R.run(() -> service.createReceivable(po.getId()));
  }

  @Operation(summary = "全部")
  @GetMapping("all-1")
  public R<List<StockOutRawMaterialItemVo>> all1(
    StockOutRawMaterialSearchParamPo search
  ) {
    JwtUserInfo jwtUserInfo = JwtUserInfo.fromHeader();
    if (jwtUserInfo != null) {
      search.setCurrentUserId(jwtUserInfo.getUserId());
    }
    return R.data(() -> service.all1(search));
  }

  @Operation(summary = "全部分页")
  @GetMapping("all-1Page")
  public R<Page<StockOutRawMaterialItemVo>> all1Page(
    StockOutRawMaterialSearchParamPo search
  ) {
    JwtUserInfo jwtUserInfo = JwtUserInfo.fromHeader();
    if (jwtUserInfo != null) {
      search.setCurrentUserId(jwtUserInfo.getUserId());
    }
    return R.data(() -> service.all1Page(search));
  }

  @Operation(summary = "全部包括子表的查询结果")
  @GetMapping("all-1Page-with-child")
  public R<Page<?>> all1PageWithChild(StockOutRawMaterialSearchParamPo search) {
    JwtUserInfo jwtUserInfo = JwtUserInfo.fromHeader();
    if (jwtUserInfo != null) {
      search.setCurrentUserId(jwtUserInfo.getUserId());
    }
    return R.data(service.all1PageWithChildSearch(search));
  }

  @Operation(summary = "全部最后更新时间")
  @GetMapping("all-1LastUpdateTime")
  public R<Date> all1LastUpdateTime(StockOutRawMaterialSearchParamPo search) {
    JwtUserInfo jwtUserInfo = JwtUserInfo.fromHeader();
    if (jwtUserInfo != null) {
      search.setCurrentUserId(jwtUserInfo.getUserId());
    }
    return R.data(() -> service.all1LastUpdateTime(search));
  }

  @Operation(summary = "待提交")
  @GetMapping("changes-to-be-committed")
  public R<List<StockOutRawMaterialItemVo>> changesToBeCommitted(
    StockOutRawMaterialSearchParamPo search
  ) {
    JwtUserInfo jwtUserInfo = JwtUserInfo.fromHeader();
    if (jwtUserInfo != null) {
      search.setCurrentUserId(jwtUserInfo.getUserId());
    }
    return R.data(() -> service.changesToBeCommitted(search));
  }

  @Operation(summary = "待提交分页")
  @GetMapping("changes-to-be-committedPage")
  public R<Page<StockOutRawMaterialItemVo>> changesToBeCommittedPage(
    StockOutRawMaterialSearchParamPo search
  ) {
    JwtUserInfo jwtUserInfo = JwtUserInfo.fromHeader();
    if (jwtUserInfo != null) {
      search.setCurrentUserId(jwtUserInfo.getUserId());
    }
    return R.data(() -> service.changesToBeCommittedPage(search));
  }

  @Operation(summary = "待提交包括子表的查询结果")
  @GetMapping("changes-to-be-committedPage-with-child")
  public R<Page<?>> changesToBeCommittedPageWithChild(
    StockOutRawMaterialSearchParamPo search
  ) {
    JwtUserInfo jwtUserInfo = JwtUserInfo.fromHeader();
    if (jwtUserInfo != null) {
      search.setCurrentUserId(jwtUserInfo.getUserId());
    }
    return R.data(service.changesToBeCommittedPageWithChildSearch(search));
  }

  @Operation(summary = "待提交最后更新时间")
  @GetMapping("changes-to-be-committedLastUpdateTime")
  public R<Date> changesToBeCommittedLastUpdateTime(
    StockOutRawMaterialSearchParamPo search
  ) {
    JwtUserInfo jwtUserInfo = JwtUserInfo.fromHeader();
    if (jwtUserInfo != null) {
      search.setCurrentUserId(jwtUserInfo.getUserId());
    }
    return R.data(() -> service.changesToBeCommittedLastUpdateTime(search));
  }

  @Operation(summary = "待出库")
  @GetMapping("waiting-for-delivery")
  public R<List<StockOutRawMaterialItemVo>> waitingForDelivery(
    StockOutRawMaterialSearchParamPo search
  ) {
    JwtUserInfo jwtUserInfo = JwtUserInfo.fromHeader();
    if (jwtUserInfo != null) {
      search.setCurrentUserId(jwtUserInfo.getUserId());
    }
    return R.data(() -> service.waitingForDelivery(search));
  }

  @Operation(summary = "待出库分页")
  @GetMapping("waiting-for-deliveryPage")
  public R<Page<StockOutRawMaterialItemVo>> waitingForDeliveryPage(
    StockOutRawMaterialSearchParamPo search
  ) {
    JwtUserInfo jwtUserInfo = JwtUserInfo.fromHeader();
    if (jwtUserInfo != null) {
      search.setCurrentUserId(jwtUserInfo.getUserId());
    }
    return R.data(() -> service.waitingForDeliveryPage(search));
  }

  @Operation(summary = "待出库包括子表的查询结果")
  @GetMapping("waiting-for-deliveryPage-with-child")
  public R<Page<?>> waitingForDeliveryPageWithChild(
    StockOutRawMaterialSearchParamPo search
  ) {
    JwtUserInfo jwtUserInfo = JwtUserInfo.fromHeader();
    if (jwtUserInfo != null) {
      search.setCurrentUserId(jwtUserInfo.getUserId());
    }
    return R.data(service.waitingForDeliveryPageWithChildSearch(search));
  }

  @Operation(summary = "待出库最后更新时间")
  @GetMapping("waiting-for-deliveryLastUpdateTime")
  public R<Date> waitingForDeliveryLastUpdateTime(
    StockOutRawMaterialSearchParamPo search
  ) {
    JwtUserInfo jwtUserInfo = JwtUserInfo.fromHeader();
    if (jwtUserInfo != null) {
      search.setCurrentUserId(jwtUserInfo.getUserId());
    }
    return R.data(() -> service.waitingForDeliveryLastUpdateTime(search));
  }

  @Operation(summary = "已完成")
  @GetMapping("done")
  public R<List<StockOutRawMaterialItemVo>> done(
    StockOutRawMaterialSearchParamPo search
  ) {
    JwtUserInfo jwtUserInfo = JwtUserInfo.fromHeader();
    if (jwtUserInfo != null) {
      search.setCurrentUserId(jwtUserInfo.getUserId());
    }
    return R.data(() -> service.done(search));
  }

  @Operation(summary = "已完成分页")
  @GetMapping("donePage")
  public R<Page<StockOutRawMaterialItemVo>> donePage(
    StockOutRawMaterialSearchParamPo search
  ) {
    JwtUserInfo jwtUserInfo = JwtUserInfo.fromHeader();
    if (jwtUserInfo != null) {
      search.setCurrentUserId(jwtUserInfo.getUserId());
    }
    return R.data(() -> service.donePage(search));
  }

  @Operation(summary = "已完成包括子表的查询结果")
  @GetMapping("donePage-with-child")
  public R<Page<?>> donePageWithChild(StockOutRawMaterialSearchParamPo search) {
    JwtUserInfo jwtUserInfo = JwtUserInfo.fromHeader();
    if (jwtUserInfo != null) {
      search.setCurrentUserId(jwtUserInfo.getUserId());
    }
    return R.data(service.donePageWithChildSearch(search));
  }

  @Operation(summary = "已完成最后更新时间")
  @GetMapping("doneLastUpdateTime")
  public R<Date> doneLastUpdateTime(StockOutRawMaterialSearchParamPo search) {
    JwtUserInfo jwtUserInfo = JwtUserInfo.fromHeader();
    if (jwtUserInfo != null) {
      search.setCurrentUserId(jwtUserInfo.getUserId());
    }
    return R.data(() -> service.doneLastUpdateTime(search));
  }

  @Operation(summary = "已撤销")
  @GetMapping("undone")
  public R<List<StockOutRawMaterialItemVo>> undone(
    StockOutRawMaterialSearchParamPo search
  ) {
    JwtUserInfo jwtUserInfo = JwtUserInfo.fromHeader();
    if (jwtUserInfo != null) {
      search.setCurrentUserId(jwtUserInfo.getUserId());
    }
    return R.data(() -> service.undone(search));
  }

  @Operation(summary = "已撤销分页")
  @GetMapping("undonePage")
  public R<Page<StockOutRawMaterialItemVo>> undonePage(
    StockOutRawMaterialSearchParamPo search
  ) {
    JwtUserInfo jwtUserInfo = JwtUserInfo.fromHeader();
    if (jwtUserInfo != null) {
      search.setCurrentUserId(jwtUserInfo.getUserId());
    }
    return R.data(() -> service.undonePage(search));
  }

  @Operation(summary = "已撤销包括子表的查询结果")
  @GetMapping("undonePage-with-child")
  public R<Page<?>> undonePageWithChild(
    StockOutRawMaterialSearchParamPo search
  ) {
    JwtUserInfo jwtUserInfo = JwtUserInfo.fromHeader();
    if (jwtUserInfo != null) {
      search.setCurrentUserId(jwtUserInfo.getUserId());
    }
    return R.data(service.undonePageWithChildSearch(search));
  }

  @Operation(summary = "已撤销最后更新时间")
  @GetMapping("undoneLastUpdateTime")
  public R<Date> undoneLastUpdateTime(StockOutRawMaterialSearchParamPo search) {
    JwtUserInfo jwtUserInfo = JwtUserInfo.fromHeader();
    if (jwtUserInfo != null) {
      search.setCurrentUserId(jwtUserInfo.getUserId());
    }
    return R.data(() -> service.undoneLastUpdateTime(search));
  }
}
